require('dotenv').config()
const { ApolloServer } = require('apollo-server')
const { RedisCache } = require('apollo-server-cache-redis')

const redis = require('redis')

const schema = require('./schema')

const { getUser } = require('./utils')

const redisOption = {
  host: process.env.REDIS_HOST,
  port: process.env.REDIS_PORT,
  password: process.env.REDIS_PASSWORD
}
console.log(process.env.REDIS_HOST)
console.log(redisOption)

// const environment = process.env.NODE_ENV || 'development'

// init redis client
const client = redis.createClient(redisOption)
client.on('error', error => {
  console.error(error)
})
let apollo
client.on('connect', () => {
  console.log('redis connected')
  schema(client)
    .then(result => {
      apollo = new ApolloServer({
        /* typeDefs, resolvers, dataSources */
        schema: result,
        cache: new RedisCache(redisOption),
        context: ({ req }) => {
          // console.log(req)
          // 通过 token 获取 redis 中的 user
          // get the user token from the headers
          const token = req.headers.authorization
            ? req.headers.authorization.substring(7)
            : ''

          // try to retrieve a user with the token
          const user = getUser(token)

          // add the user to the context
          return {
            req,
            user
          }
        },
        formatError: error => {
          console.log(error)
          // return new Error('Internal server error')
          // Or, you can delete the exception information
          // delete error.extensions.exception
          return error
          // return new ApolloError('error')
        }
      })

      apollo.listen({ port: 4000 }).then(({ url }) => {
        console.log(`🚀 Server ready at ${url}`)
        try {
          // 通知 pm2 准备好了
          process.send('ready')
        } catch (error) {
          console.log(error)
        }
      })
    })
    .catch(error => console.log(error))
})

// 拦截关机指令
process.on('SIGINT', () => {
  console.info('SIGINT signal received.')

  apollo.httpServer.close(error => {
    if (error) {
      console.log(error)
      process.exit(1)
    }
    console.log('apollo httpServer closed')
    apollo.subscriptionServer.close(err => {
      if (err) {
        console.log(err)
      }
      console.log('apollo subscriptionServer closed')
    })
    client.end(true)
    console.log('redis client closed')
  })
})

// 当信号不可用时，您的进程将被终止。 在这种情况下，您需要遵从 shutdown事件
process.on('message', msg => {
  if (msg === 'shutdown') {
    console.log('Closing all connections...')
    setTimeout(() => {
      console.log('Finished closing connections')
      process.exit(0)
    }, 1500)
  }
})
